package com.wanghua.spring.filter.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;

/*
* 为简单起见，这个request并没有覆盖 getParameterNames 等方法，也没有处理多个 checkbox 提交相同数据的情况。
* */
public class UploadRequestWrapper extends HttpServletRequestWrapper {
	private static final String MULTIPART_HEADER = "Content-type";  //文件类型头
	private boolean multipart;  //是否是上传文件
	private Map<String, Object> params = new HashMap<String, Object>(); //map，保存所有的域

	@SuppressWarnings("all")
	public UploadRequestWrapper(HttpServletRequest request) {
		super(request);

		// 判断是否为上传文件
		multipart = request.getHeader(MULTIPART_HEADER) != null && request.getHeader(MULTIPART_HEADER).startsWith("multipart/form-data");
		if (multipart) {
			try {
				// 使用apache的工具解析
				DiskFileUpload upload = new DiskFileUpload();
				upload.setHeaderEncoding("utf8");

				// 解析，获得所有的文本域与文件域
				List<FileItem> fileItems = upload.parseRequest(request);

				for (Iterator<FileItem> it = fileItems.iterator(); it.hasNext(); ) {
					// 遍历
					FileItem item = it.next();
					if (item.isFormField()) {
						// 如果是文本域，直接放到map里
						params.put(item.getFieldName(), item.getString("utf8"));
					} else {
						// 否则，为文件，先获取文件名称
						String filename = item.getName().replace("\\", "/");
						filename = filename.substring(filename.lastIndexOf("/") + 1);

						// 保存文件内容
						File file = new File(System.getProperty("java.io.tmpdir"), filename);  //java.io.tmpdir；操作系统不同 这个系统属性所表示的目录也不同——默认是系统的临时目录
						OutputStream ous = new FileOutputStream(file);
						ous.write(item.get());
						ous.close();

						// 放到map中
						params.put(item.getFieldName(), file);
					}
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	//request.getAttribute()方法返回request范围内存在的对象。getAttribute得到的都是Object类型的
	@Override
	public Object getAttribute(String name) {
		// 如果为上传文件，则从map中取值
		if (multipart && params.containsKey(name)) {
			return params.get(name);
		}
		return super.getAttribute(name);
	}

	//request.getParameter()方法是获取http提交过来的数据，getParameter得到的都是String类型的
	@Override
	public String getParameter(String name) {
		// 如果为上传文件，则从map中取值
		if (multipart && params.containsKey(name)) {
			return params.get(name).toString();
		}
		return super.getParameter(name);
	}

	//总的来说：request.getAttribute()方法返回request范围内存在的对象，而request.getParameter()方法是获取http提交过来的数据。
}
